﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProxyPattern
{
    abstract class UserSubject
    {
        public abstract bool Login(string username, string password);
    }

    class User : UserSubject
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Token { get; set; }
        public override bool Login(string username, string password)
        {
            this.UserName = username;
            this.Password = password;
            this.Email = "demo@163.com";
            this.Phone = "12345678901";
            this.Token = Guid.NewGuid().ToString();
            return true;
        }
    }

    class UserProxy : UserSubject
    {
        public string UserName { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Token { get; set; }

        User user = new User();
        public override bool Login(string username, string password)
        {
            bool res = user.Login(username, password);

            this.UserName = user.UserName;
            this.Email = user.Email;
            this.Phone = user.Phone;
            this.Token = user.Token;

            return res;
        }
    }

    abstract class Abstraction
    {
        public abstract void Operation(string name);
    }

    class Concrete : Abstraction
    {
        public override void Operation(string name)
        {
            Console.WriteLine("具体的" + name);
        }
    }

    class AbstractionProxy : Abstraction
    {
        Concrete console = new Concrete();
        public override void Operation(string name)
        {
            console.Operation(name);
        }
    }


    //代理模式：给某一个对象提供一个代理或占位符，并由代理对象来控制对原对象的访问。
    // (1) Subject（抽象主题角色）：它声明了真实主题和代理主题的共同接口，这样一来在任何使用真实主题的地方都可以使用代理主题，客户端通常需要针对抽象主题角色进行编程。
    // (2) Proxy（代理主题角色）：它包含了对真实主题的引用，从而可以在任何时候操作真实主题对象；在代理主题角色中提供一个与真实主题角色相同的接口，以便在任何时候都可以替代真实主题；
    // 代理主题角色还可以控制对真实主题的使用，负责在需要的时候创建和删除真实主题对象，并对真实主题对象的使用加以约束。通常，在代理主题角色中，客户端在调用所引用的真实主题操作之前或之后还需要执行其他操作，
    // 而不仅仅是单纯调用真实主题对象中的操作。
    // (3) RealSubject（真实主题角色）：它定义了代理角色所代表的真实对象，在真实主题角色中实现了真实的业务操作，客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。
    // name  password
    class Program
    {
        static void Main(string[] args)
        {
            AbstractionProxy abstractionProxy = new AbstractionProxy();
            abstractionProxy.Operation("china");


            //User user = new User();
            //user.Login("tom", "123456");

            //UserProxy user = new UserProxy();
            //user.Login("tom", "123456");
            //Console.WriteLine($"{user.UserName},{user.Email},{user.Phone},{user.Token}");
            //Console.Read();
        }


    }
}
